{
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Quantum Kernel Methods for IRIS dataset classification with [TorchQuantum](https://github.com/mit-han-lab/torchquantum).\n",
        "<p align=\"left\">\n",
        "<img src=\"https://github.com/mit-han-lab/torchquantum/blob/master/torchquantum_logo.jpg?raw=true\" alt=\"torchquantum Logo\" width=\"250\">\n",
        "</p>\n",
        "\n",
        "Tutorial Author: Zirui Li, Hanrui Wang\n"
      ],
      "metadata": {
        "id": "_IbXAq46NDHo"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "###Outline\n",
        "1. Introduction to Quantum Kernel Methods.\n",
        "2. Build and train an SVM using Quantum Kernel Methods.\n",
        "\n",
        "In this tutorial, we use `tq.op_name_dict`, `tq.functional.func_name_dict` and `tq.QuantumDevice` from TorchQuantum.\n",
        "\n",
        "You can learn how to build a Quantum kernel function and train an SVM with the quantum kernel from this tutorial.\n"
      ],
      "metadata": {
        "id": "01AwyLuHUFbX"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "##Introduction to Quantum Kernel Methods.\n"
      ],
      "metadata": {
        "id": "slU3ib_mURDX"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "###Kernel Methods\n",
        "Kernels or kernel methods (also called Kernel functions) are sets of different types of algorithms that are being used for pattern analysis. They are used to solve a non-linear problem by a linear classifier. Kernels Methods are employed in SVM (Support Vector Machines) which are often used in classification and regression problems. The SVM uses what is called a “Kernel Trick” where the data is transformed and an optimal boundary is found for the possible outputs.\n",
        "\n",
        "\n",
        "####Quantum Kernel\n",
        "Quantum circuit can transfer the data to a high dimension Hilbert space which is hard to simulate on classical computer. Using kernel methods based on this Hilbert space can achieve unexpected performance."
      ],
      "metadata": {
        "id": "qJv0wED75YTq"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "###How to evaluate the distance in Hilbert space?\n",
        "Assume S(x) is the unitary that transfer data x to the state in Hilbert space. To evaluate the inner product between S(x) and S(y), we add a Transpose Conjugation of S(y) behind S(x) and measure the probability that the state falls on $|00\\cdots0\\rangle$"
      ],
      "metadata": {
        "id": "d4zraAesQ2vr"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "\n",
        "<div align=\"center\">\n",
        "<img src=\"https://github.com/mit-han-lab/torchquantum/blob/master/figs/kernel.png?raw=true\" alt=\"conv-full-layer\" width=\"600\">\n",
        "</div>"
      ],
      "metadata": {
        "id": "ECUDI-rESEkj"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "##Build and train an SVM using Quantum Kernel Methods."
      ],
      "metadata": {
        "id": "tOv-XfNjW5XH"
      }
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pfwd2SNaOA4z"
      },
      "source": [
        "###Installation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "azb47tvSiaBp",
        "outputId": "d21454a9-cb10-457e-cf24-d52b00c00077"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Collecting qiskit==0.32.1\n",
            "  Downloading qiskit-0.32.1.tar.gz (13 kB)\n",
            "Collecting qiskit-terra==0.18.3\n",
            "  Downloading qiskit_terra-0.18.3-cp37-cp37m-manylinux2010_x86_64.whl (6.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 6.1 MB 4.3 MB/s \n",
            "\u001b[?25hCollecting qiskit-aer==0.9.1\n",
            "  Downloading qiskit_aer-0.9.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (17.9 MB)\n",
            "\u001b[K     |████████████████████████████████| 17.9 MB 1.3 MB/s \n",
            "\u001b[?25hCollecting qiskit-ibmq-provider==0.18.1\n",
            "  Downloading qiskit_ibmq_provider-0.18.1-py3-none-any.whl (237 kB)\n",
            "\u001b[K     |████████████████████████████████| 237 kB 62.2 MB/s \n",
            "\u001b[?25hCollecting qiskit-ignis==0.6.0\n",
            "  Downloading qiskit_ignis-0.6.0-py3-none-any.whl (207 kB)\n",
            "\u001b[K     |████████████████████████████████| 207 kB 60.0 MB/s \n",
            "\u001b[?25hCollecting qiskit-aqua==0.9.5\n",
            "  Downloading qiskit_aqua-0.9.5-py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 55.7 MB/s \n",
            "\u001b[?25hRequirement already satisfied: scipy>=1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aer==0.9.1->qiskit==0.32.1) (1.4.1)\n",
            "Requirement already satisfied: numpy>=1.16.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-aer==0.9.1->qiskit==0.32.1) (1.19.5)\n",
            "Requirement already satisfied: h5py<3.3.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (3.1.0)\n",
            "Collecting docplex>=2.21.207\n",
            "  Downloading docplex-2.22.213.tar.gz (634 kB)\n",
            "\u001b[K     |████████████████████████████████| 634 kB 32.5 MB/s \n",
            "\u001b[?25hRequirement already satisfied: scikit-learn>=0.20.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (1.0.2)\n",
            "Collecting dlx<=1.0.4\n",
            "  Downloading dlx-1.0.4.tar.gz (5.5 kB)\n",
            "Requirement already satisfied: setuptools>=40.1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (57.4.0)\n",
            "Requirement already satisfied: psutil>=5 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (5.4.8)\n",
            "Requirement already satisfied: fastdtw<=0.3.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (0.3.4)\n",
            "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (1.3.5)\n",
            "Collecting quandl\n",
            "  Downloading Quandl-3.7.0-py2.py3-none-any.whl (26 kB)\n",
            "Collecting retworkx>=0.8.0\n",
            "  Downloading retworkx-0.11.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.6 MB)\n",
            "\u001b[K     |████████████████████████████████| 1.6 MB 52.2 MB/s \n",
            "\u001b[?25hCollecting yfinance>=0.1.62\n",
            "  Downloading yfinance-0.1.70-py2.py3-none-any.whl (26 kB)\n",
            "Requirement already satisfied: sympy>=1.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit==0.32.1) (1.7.1)\n",
            "Collecting requests-ntlm>=1.1.0\n",
            "  Downloading requests_ntlm-1.1.0-py2.py3-none-any.whl (5.7 kB)\n",
            "Collecting websocket-client>=1.0.1\n",
            "  Downloading websocket_client-1.2.3-py3-none-any.whl (53 kB)\n",
            "\u001b[K     |████████████████████████████████| 53 kB 2.3 MB/s \n",
            "\u001b[?25hRequirement already satisfied: python-dateutil>=2.8.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.8.2)\n",
            "Requirement already satisfied: urllib3>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (1.24.3)\n",
            "Requirement already satisfied: requests>=2.19 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.23.0)\n",
            "Requirement already satisfied: dill>=0.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit==0.32.1) (0.3.4)\n",
            "Collecting symengine>0.7\n",
            "  Downloading symengine-0.8.1-cp37-cp37m-manylinux2010_x86_64.whl (38.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 38.2 MB 1.2 MB/s \n",
            "\u001b[?25hCollecting ply>=3.10\n",
            "  Downloading ply-3.11-py2.py3-none-any.whl (49 kB)\n",
            "\u001b[K     |████████████████████████████████| 49 kB 6.3 MB/s \n",
            "\u001b[?25hCollecting fastjsonschema>=2.10\n",
            "  Downloading fastjsonschema-2.15.3-py3-none-any.whl (22 kB)\n",
            "Collecting tweedledum<2.0,>=1.1\n",
            "  Downloading tweedledum-1.1.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (943 kB)\n",
            "\u001b[K     |████████████████████████████████| 943 kB 59.9 MB/s \n",
            "\u001b[?25hRequirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit==0.32.1) (4.3.3)\n",
            "Collecting python-constraint>=1.4\n",
            "  Downloading python-constraint-1.4.0.tar.bz2 (18 kB)\n",
            "Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from docplex>=2.21.207->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.15.0)\n",
            "Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<3.3.0->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.5.2)\n",
            "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (0.18.1)\n",
            "Requirement already satisfied: importlib-resources>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (5.4.0)\n",
            "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (3.10.0.2)\n",
            "Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (4.10.1)\n",
            "Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (21.4.0)\n",
            "Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from importlib-resources>=1.4.0->jsonschema>=2.6->qiskit-terra==0.18.3->qiskit==0.32.1) (3.7.0)\n",
            "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (3.0.4)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2021.10.8)\n",
            "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.10)\n",
            "Collecting cryptography>=1.3\n",
            "  Downloading cryptography-36.0.1-cp36-abi3-manylinux_2_24_x86_64.whl (3.6 MB)\n",
            "\u001b[K     |████████████████████████████████| 3.6 MB 53.7 MB/s \n",
            "\u001b[?25hCollecting ntlm-auth>=1.0.2\n",
            "  Downloading ntlm_auth-1.5.0-py2.py3-none-any.whl (29 kB)\n",
            "Requirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.7/dist-packages (from cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (1.15.0)\n",
            "Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from cffi>=1.12->cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.21)\n",
            "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit==0.32.1) (3.1.0)\n",
            "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.1.0)\n",
            "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy>=1.3->qiskit-aqua==0.9.5->qiskit==0.32.1) (1.2.1)\n",
            "Collecting requests>=2.19\n",
            "  Downloading requests-2.27.1-py2.py3-none-any.whl (63 kB)\n",
            "\u001b[K     |████████████████████████████████| 63 kB 1.9 MB/s \n",
            "\u001b[?25hRequirement already satisfied: multitasking>=0.0.7 in /usr/local/lib/python3.7/dist-packages (from yfinance>=0.1.62->qiskit-aqua==0.9.5->qiskit==0.32.1) (0.0.10)\n",
            "Collecting lxml>=4.5.1\n",
            "  Downloading lxml-4.7.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (6.4 MB)\n",
            "\u001b[K     |████████████████████████████████| 6.4 MB 23.4 MB/s \n",
            "\u001b[?25hRequirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas->qiskit-aqua==0.9.5->qiskit==0.32.1) (2018.9)\n",
            "Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit==0.32.1) (2.0.11)\n",
            "Collecting inflection>=0.3.1\n",
            "  Downloading inflection-0.5.1-py2.py3-none-any.whl (9.5 kB)\n",
            "Requirement already satisfied: more-itertools in /usr/local/lib/python3.7/dist-packages (from quandl->qiskit-aqua==0.9.5->qiskit==0.32.1) (8.12.0)\n",
            "Building wheels for collected packages: qiskit, dlx, docplex, python-constraint\n",
            "  Building wheel for qiskit (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for qiskit: filename=qiskit-0.32.1-py3-none-any.whl size=11777 sha256=16a15d5cc4c9bdab55b6da049c7e58a7c58cd02e22ecc9044718a27788244262\n",
            "  Stored in directory: /root/.cache/pip/wheels/0f/62/0a/c53eda1ead41c137c47c9730bc2771a8367b1ce00fb64e8cc6\n",
            "  Building wheel for dlx (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for dlx: filename=dlx-1.0.4-py3-none-any.whl size=5718 sha256=a8f563a7d9277a099dc3b0dc15762e4def17093a161e6fbf4d733b6b0b2f1c2a\n",
            "  Stored in directory: /root/.cache/pip/wheels/78/55/c8/dc61e772445a566b7608a476d151e9dcaf4e092b01b0c4bc3c\n",
            "  Building wheel for docplex (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for docplex: filename=docplex-2.22.213-py3-none-any.whl size=696882 sha256=57bb12d24c9ce9789526ae87226c1d3a0e9c1f65f4c3dab2072c2c4fe4a86a1d\n",
            "  Stored in directory: /root/.cache/pip/wheels/90/69/6b/1375c68a5b7ff94c40263b151c86f58bd72200bf0c465b5ba3\n",
            "  Building wheel for python-constraint (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for python-constraint: filename=python_constraint-1.4.0-py2.py3-none-any.whl size=24081 sha256=ed53d7d29290e0b27910e22334e2833b1157a35ce940f011456cb4aace39c774\n",
            "  Stored in directory: /root/.cache/pip/wheels/07/27/db/1222c80eb1e431f3d2199c12569cb1cac60f562a451fe30479\n",
            "Successfully built qiskit dlx docplex python-constraint\n",
            "Installing collected packages: tweedledum, symengine, retworkx, python-constraint, ply, fastjsonschema, requests, qiskit-terra, ntlm-auth, lxml, inflection, cryptography, yfinance, websocket-client, requests-ntlm, quandl, qiskit-ignis, docplex, dlx, qiskit-ibmq-provider, qiskit-aqua, qiskit-aer, qiskit\n",
            "  Attempting uninstall: requests\n",
            "    Found existing installation: requests 2.23.0\n",
            "    Uninstalling requests-2.23.0:\n",
            "      Successfully uninstalled requests-2.23.0\n",
            "  Attempting uninstall: lxml\n",
            "    Found existing installation: lxml 4.2.6\n",
            "    Uninstalling lxml-4.2.6:\n",
            "      Successfully uninstalled lxml-4.2.6\n",
            "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
            "google-colab 1.0.0 requires requests~=2.23.0, but you have requests 2.27.1 which is incompatible.\n",
            "datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\u001b[0m\n",
            "Successfully installed cryptography-36.0.1 dlx-1.0.4 docplex-2.22.213 fastjsonschema-2.15.3 inflection-0.5.1 lxml-4.7.1 ntlm-auth-1.5.0 ply-3.11 python-constraint-1.4.0 qiskit-0.32.1 qiskit-aer-0.9.1 qiskit-aqua-0.9.5 qiskit-ibmq-provider-0.18.1 qiskit-ignis-0.6.0 qiskit-terra-0.18.3 quandl-3.7.0 requests-2.27.1 requests-ntlm-1.1.0 retworkx-0.11.0 symengine-0.8.1 tweedledum-1.1.1 websocket-client-1.2.3 yfinance-0.1.70\n"
          ]
        }
      ],
      "source": [
        "!pip install qiskit==0.32.1"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "F2-0UpluOIQl"
      },
      "source": [
        "Download and cd to the repo."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6sNqLl9tjjAf",
        "outputId": "90867afc-49c0-4668-d07e-889f5f8ba3f3"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Cloning into 'pytorch-quantum'...\n",
            "remote: Enumerating objects: 10724, done.\u001b[K\n",
            "remote: Counting objects: 100% (7516/7516), done.\u001b[K\n",
            "remote: Compressing objects: 100% (3769/3769), done.\u001b[K\n",
            "remote: Total 10724 (delta 3756), reused 7069 (delta 3343), pack-reused 3208\u001b[K\n",
            "Receiving objects: 100% (10724/10724), 3.19 MiB | 21.64 MiB/s, done.\n",
            "Resolving deltas: 100% (5723/5723), done.\n",
            "Checking out files: 100% (50054/50054), done.\n"
          ]
        }
      ],
      "source": [
        "!git clone https://github.com/mit-han-lab/pytorch-quantum.git"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0c2MCqFXjxkD",
        "outputId": "44c664ed-a0fe-42a1-ee78-8412111d3d30"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "/content/pytorch-quantum\n"
          ]
        }
      ],
      "source": [
        "%cd pytorch-quantum"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PO1xLbaOOxWk"
      },
      "source": [
        "Install torch-quantum."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3c6nfq3KkVXG",
        "outputId": "80a4f321-ebb0-4923-8dab-a05ef1719fb9"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Obtaining file:///content/pytorch-quantum\n",
            "Requirement already satisfied: numpy>=1.19.2 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (1.19.5)\n",
            "Requirement already satisfied: torchvision>=0.9.0.dev20210130 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (0.11.1+cu111)\n",
            "Requirement already satisfied: tqdm>=4.56.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (4.62.3)\n",
            "Requirement already satisfied: setuptools>=52.0.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (57.4.0)\n",
            "Requirement already satisfied: torch>=1.8.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (1.10.0+cu111)\n",
            "Collecting torchpack>=0.3.0\n",
            "  Downloading torchpack-0.3.1-py3-none-any.whl (34 kB)\n",
            "Requirement already satisfied: qiskit>=0.32.0 in /usr/local/lib/python3.7/dist-packages (from torchquantum==0.1.0) (0.32.1)\n",
            "Collecting matplotlib>=3.3.2\n",
            "  Downloading matplotlib-3.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (11.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 11.2 MB 7.9 MB/s \n",
            "\u001b[?25hCollecting pathos>=0.2.7\n",
            "  Downloading pathos-0.2.8-py2.py3-none-any.whl (81 kB)\n",
            "\u001b[K     |████████████████████████████████| 81 kB 4.9 MB/s \n",
            "\u001b[?25hRequirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (2.8.2)\n",
            "Requirement already satisfied: pyparsing>=2.2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (3.0.7)\n",
            "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (0.11.0)\n",
            "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (1.3.2)\n",
            "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (21.3)\n",
            "Collecting fonttools>=4.22.0\n",
            "  Downloading fonttools-4.29.1-py3-none-any.whl (895 kB)\n",
            "\u001b[K     |████████████████████████████████| 895 kB 49.7 MB/s \n",
            "\u001b[?25hRequirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.7/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.0) (7.1.2)\n",
            "Requirement already satisfied: multiprocess>=0.70.12 in /usr/local/lib/python3.7/dist-packages (from pathos>=0.2.7->torchquantum==0.1.0) (0.70.12.2)\n",
            "Collecting pox>=0.3.0\n",
            "  Downloading pox-0.3.0-py2.py3-none-any.whl (30 kB)\n",
            "Collecting ppft>=1.6.6.4\n",
            "  Downloading ppft-1.6.6.4-py3-none-any.whl (65 kB)\n",
            "\u001b[K     |████████████████████████████████| 65 kB 2.6 MB/s \n",
            "\u001b[?25hRequirement already satisfied: dill>=0.3.4 in /usr/local/lib/python3.7/dist-packages (from pathos>=0.2.7->torchquantum==0.1.0) (0.3.4)\n",
            "Requirement already satisfied: six>=1.7.3 in /usr/local/lib/python3.7/dist-packages (from ppft>=1.6.6.4->pathos>=0.2.7->torchquantum==0.1.0) (1.15.0)\n",
            "Requirement already satisfied: qiskit-aqua==0.9.5 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.9.5)\n",
            "Requirement already satisfied: qiskit-ignis==0.6.0 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.6.0)\n",
            "Requirement already satisfied: qiskit-terra==0.18.3 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.18.3)\n",
            "Requirement already satisfied: qiskit-ibmq-provider==0.18.1 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.18.1)\n",
            "Requirement already satisfied: qiskit-aer==0.9.1 in /usr/local/lib/python3.7/dist-packages (from qiskit>=0.32.0->torchquantum==0.1.0) (0.9.1)\n",
            "Requirement already satisfied: scipy>=1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aer==0.9.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.4.1)\n",
            "Requirement already satisfied: h5py<3.3.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (3.1.0)\n",
            "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.3.5)\n",
            "Requirement already satisfied: quandl in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (3.7.0)\n",
            "Requirement already satisfied: docplex>=2.21.207 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (2.22.213)\n",
            "Requirement already satisfied: psutil>=5 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (5.4.8)\n",
            "Requirement already satisfied: dlx<=1.0.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.0.4)\n",
            "Requirement already satisfied: retworkx>=0.8.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.11.0)\n",
            "Requirement already satisfied: yfinance>=0.1.62 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.1.70)\n",
            "Requirement already satisfied: fastdtw<=0.3.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.3.4)\n",
            "Requirement already satisfied: scikit-learn>=0.20.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.0.2)\n",
            "Requirement already satisfied: sympy>=1.3 in /usr/local/lib/python3.7/dist-packages (from qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.7.1)\n",
            "Requirement already satisfied: urllib3>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.24.3)\n",
            "Requirement already satisfied: websocket-client>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.2.3)\n",
            "Requirement already satisfied: requests-ntlm>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.1.0)\n",
            "Requirement already satisfied: requests>=2.19 in /usr/local/lib/python3.7/dist-packages (from qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.27.1)\n",
            "Requirement already satisfied: symengine>0.7 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (0.8.1)\n",
            "Requirement already satisfied: tweedledum<2.0,>=1.1 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (1.1.1)\n",
            "Requirement already satisfied: ply>=3.10 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (3.11)\n",
            "Requirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (4.3.3)\n",
            "Requirement already satisfied: fastjsonschema>=2.10 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (2.15.3)\n",
            "Requirement already satisfied: python-constraint>=1.4 in /usr/local/lib/python3.7/dist-packages (from qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (1.4.0)\n",
            "Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<3.3.0->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.5.2)\n",
            "Requirement already satisfied: importlib-resources>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (5.4.0)\n",
            "Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (21.4.0)\n",
            "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (0.18.1)\n",
            "Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (4.10.1)\n",
            "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (3.10.0.2)\n",
            "Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from importlib-resources>=1.4.0->jsonschema>=2.6->qiskit-terra==0.18.3->qiskit>=0.32.0->torchquantum==0.1.0) (3.7.0)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.10)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2021.10.8)\n",
            "Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.0.11)\n",
            "Requirement already satisfied: ntlm-auth>=1.0.2 in /usr/local/lib/python3.7/dist-packages (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.5.0)\n",
            "Requirement already satisfied: cryptography>=1.3 in /usr/local/lib/python3.7/dist-packages (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (36.0.1)\n",
            "Requirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.7/dist-packages (from cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (1.15.0)\n",
            "Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from cffi>=1.12->cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.18.1->qiskit>=0.32.0->torchquantum==0.1.0) (2.21)\n",
            "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (3.1.0)\n",
            "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.20.0->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.1.0)\n",
            "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.7/dist-packages (from sympy>=1.3->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (1.2.1)\n",
            "Collecting multimethod\n",
            "  Downloading multimethod-1.7-py3-none-any.whl (9.5 kB)\n",
            "Requirement already satisfied: tensorboard in /usr/local/lib/python3.7/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.0) (2.7.0)\n",
            "Collecting toml\n",
            "  Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB)\n",
            "Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.0) (3.13)\n",
            "Collecting tensorpack\n",
            "  Downloading tensorpack-0.11-py2.py3-none-any.whl (296 kB)\n",
            "\u001b[K     |████████████████████████████████| 296 kB 59.7 MB/s \n",
            "\u001b[?25hCollecting loguru\n",
            "  Downloading loguru-0.6.0-py3-none-any.whl (58 kB)\n",
            "\u001b[K     |████████████████████████████████| 58 kB 6.4 MB/s \n",
            "\u001b[?25hRequirement already satisfied: lxml>=4.5.1 in /usr/local/lib/python3.7/dist-packages (from yfinance>=0.1.62->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (4.7.1)\n",
            "Requirement already satisfied: multitasking>=0.0.7 in /usr/local/lib/python3.7/dist-packages (from yfinance>=0.1.62->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.0.10)\n",
            "Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (2018.9)\n",
            "Requirement already satisfied: inflection>=0.3.1 in /usr/local/lib/python3.7/dist-packages (from quandl->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (0.5.1)\n",
            "Requirement already satisfied: more-itertools in /usr/local/lib/python3.7/dist-packages (from quandl->qiskit-aqua==0.9.5->qiskit>=0.32.0->torchquantum==0.1.0) (8.12.0)\n",
            "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.35.0)\n",
            "Requirement already satisfied: protobuf>=3.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (3.17.3)\n",
            "Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.37.1)\n",
            "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.0.0)\n",
            "Requirement already satisfied: grpcio>=1.24.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.43.0)\n",
            "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (3.3.6)\n",
            "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.6.1)\n",
            "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.0.1)\n",
            "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.8.1)\n",
            "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.4.6)\n",
            "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.2.8)\n",
            "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (4.8)\n",
            "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (4.2.4)\n",
            "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (1.3.1)\n",
            "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (0.4.8)\n",
            "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard->torchpack>=0.3.0->torchquantum==0.1.0) (3.2.0)\n",
            "Collecting msgpack-numpy>=0.4.4.2\n",
            "  Downloading msgpack_numpy-0.4.7.1-py2.py3-none-any.whl (6.7 kB)\n",
            "Requirement already satisfied: pyzmq>=16 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (22.3.0)\n",
            "Requirement already satisfied: msgpack>=0.5.2 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (1.0.3)\n",
            "Requirement already satisfied: termcolor>=1.1 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (1.1.0)\n",
            "Requirement already satisfied: tabulate>=0.7.7 in /usr/local/lib/python3.7/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.0) (0.8.9)\n",
            "Installing collected packages: msgpack-numpy, toml, tensorpack, ppft, pox, multimethod, loguru, fonttools, torchpack, pathos, matplotlib, torchquantum\n",
            "  Attempting uninstall: matplotlib\n",
            "    Found existing installation: matplotlib 3.2.2\n",
            "    Uninstalling matplotlib-3.2.2:\n",
            "      Successfully uninstalled matplotlib-3.2.2\n",
            "  Running setup.py develop for torchquantum\n",
            "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
            "albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.2.9 which is incompatible.\u001b[0m\n",
            "Successfully installed fonttools-4.29.1 loguru-0.6.0 matplotlib-3.5.1 msgpack-numpy-0.4.7.1 multimethod-1.7 pathos-0.2.8 pox-0.3.0 ppft-1.6.6.4 tensorpack-0.11 toml-0.10.2 torchpack-0.3.1 torchquantum-0.1.0\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.colab-display-data+json": {
              "pip_warning": {
                "packages": [
                  "matplotlib",
                  "mpl_toolkits"
                ]
              }
            }
          },
          "metadata": {}
        }
      ],
      "source": [
        "!pip install --editable ."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "18tqleq4O3cX"
      },
      "source": [
        "Change PYTHONPATH and install other packages."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "d7ZPp7FikrZz",
        "outputId": "6b66fd65-c75d-4ff6-94a7-6c17210c05e4"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "env: PYTHONPATH=.\n"
          ]
        }
      ],
      "source": [
        "%env PYTHONPATH=."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rhsBhV23PD4g"
      },
      "source": [
        "Run the following code to store a qiskit token. You can replace it with your own token from your IBMQ account if you like.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Iw9rQ6dcnrhe"
      },
      "outputs": [],
      "source": [
        "from qiskit import IBMQ\n",
        "IBMQ.save_account('0238b0afc0dc515fe7987b02706791d1719cb89b68befedc125eded0607e6e9e9f26d3eed482f66fdc45fdfceca3aab2edb9519d96b39e9c78040194b86e7858', overwrite=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "###Import the module\n",
        "`SVC` is support vector classification. We use this module to call the support vector machine algorithm.\n",
        "\n",
        "`load_iris` is to load the famous iris dataset.\n",
        "\n",
        "`StandardScaler` is to help scale the data by removing the mean and scaling to unit variance.\n",
        "\n",
        "`train_test_split` is a tool to split the dataset.\n",
        "\n",
        "`accuracy_score` can check how many samples are correctly predicted and give us the accuracy.\n",
        "\n",
        "`func_name_dict` is a very important dict under `torchquantum.functional`. If we feed the name of the gates we want, like ‘rx’, ‘ry’, or ‘rzz’, the dict will give us a function. The function plays a central role in our quantum model. It performs the specified unitary operations on a specified quantum state on a specified wire. These three specified things are the three parameters we need to pass to it. You can see that later.\n"
      ],
      "metadata": {
        "id": "-42mdL8CG5Vi"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import numpy as np\n",
        "import torch\n",
        "\n",
        "from sklearn.svm import SVC\n",
        "from sklearn.datasets import load_iris\n",
        "from sklearn.preprocessing import StandardScaler\n",
        "from sklearn.model_selection import train_test_split\n",
        "from sklearn.metrics import accuracy_score\n",
        "from torchquantum.functional import func_name_dict\n",
        "import torchquantum as tq"
      ],
      "metadata": {
        "id": "N5acspJ8G1n3"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "###Prepare dataset\n",
        "We use the front 100 samples of IRIS dataset.\n",
        "\n",
        "Since the phase in quantum gates is 2π-periodic, it is necessary to scale the data in a range from -π to π.\n",
        "\n",
        "And we change the label from 0 and 1 to -1 and 1.\n",
        "\n",
        "Split the dataset on a 3-to-1 ratio.\n"
      ],
      "metadata": {
        "id": "QiOV-xIGKXVK"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "X, y = load_iris(return_X_y=True)\n",
        "\n",
        "X = X[:100]\n",
        "y = y[:100]\n",
        "\n",
        "scaler = StandardScaler().fit(X)\n",
        "X_scaled = scaler.transform(X)\n",
        "y_scaled = 2 * (y - 0.5)\n",
        "\n",
        "X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled)"
      ],
      "metadata": {
        "id": "iBnWI5yqKfMB"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Build the Ansatz, consist of a unitary and its transpose conjugation.\n",
        "When initializing the `KernelAnsatz`, we only need to pass a `func_list` and the KernelAnsatz will record the `func_list`. Each entry in the function is a dict, containing 'input_idx', 'func', and 'wires'.\n",
        "\n",
        "When executing the `KernelAnsatz`, three parameters are passed from outside, `q_device`, `x`, and `y`. `q_device` stores the state vector. We reset the state vector to the $|00\\cdots0⟩$. And if you didn’t forget the figure, we will act the S(x) and the transpose conjugation of S(y) to the `q_device`.\n",
        "\n",
        "Here the gates in the `func_list` with data `x` form the unitary S(x). S(y)'s transpose conjugation is S(y)’s inverse matrix. From the perspective of inverse, we can build the S(y)'s transpose conjugation by inverting the function list with data `y`. So, how to invert a list of gates executed from head to tail? You only need to counteract the list of gates from tail to head one by one. So here, we simply reverse the sequence of function list and flip the phase from positive to negative or from negative to positive.\n",
        "\n",
        "And in each iteration is to act the unitary gate on the quantum state. We look up the `func_name_dict` with the function name. Here the function name is the gate name, like ‘ry’, ‘rz’ and so so. The dict returns a function. We pass the three parameters to the function and the function will act the gate on the state vector(`self.q_device`), on the `wires`, with the phase, here the `params` mean phase.\n"
      ],
      "metadata": {
        "id": "KpVfJUezK7ny"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "class KernalAnsatz(tq.QuantumModule):\n",
        "    def __init__(self, func_list):\n",
        "        super().__init__()\n",
        "        self.func_list = func_list\n",
        "    \n",
        "    @tq.static_support\n",
        "    def forward(self, q_device: tq.QuantumDevice, x, y):\n",
        "        self.q_device = q_device\n",
        "        self.q_device.reset_states(x.shape[0])\n",
        "        for info in self.func_list:\n",
        "            if tq.op_name_dict[info['func']].num_params > 0:\n",
        "                params = x[:, info['input_idx']]\n",
        "            else:\n",
        "                params = None\n",
        "            func_name_dict[info['func']](\n",
        "                self.q_device,\n",
        "                wires=info['wires'],\n",
        "                params=params,\n",
        "            )\n",
        "        for info in reversed(self.func_list):\n",
        "            if tq.op_name_dict[info['func']].num_params > 0:\n",
        "                params = -y[:, info['input_idx']]\n",
        "            else:\n",
        "                params = None\n",
        "            func_name_dict[info['func']](\n",
        "                self.q_device,\n",
        "                wires=info['wires'],\n",
        "                params=params,\n",
        "            )"
      ],
      "metadata": {
        "id": "UbhzYiGcK9xk"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Build the whole quantum circuit\n",
        "\n",
        "The whole model initialization is a 4-wire quantum state, the `tq.QuantumDevice` module can store the state vector and a `KernelAnsatz` we just mentioned.\n",
        "\n",
        "When executing the whole model, as there’s a concept of batch in torchquantum’s model, we set the batch size is 1. After executing the `KernelAnsatz`, we measure the probability that the quantum state falls on the $|00\\cdots0\\rangle$ as the result. We get the state vector, flatten it, get the first amplitude, which is also the amplitude of the $|00\\cdots0\\rangle$ state, calculate the absolute value of the amplitude, and get the probability that the quantum state falls on the $|00\\cdots0\\rangle$ state.\n"
      ],
      "metadata": {
        "id": "AXwEp5SILF_Z"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "class Kernel(tq.QuantumModule):\n",
        "    def __init__(self):\n",
        "        super().__init__()\n",
        "        self.n_wires = 4\n",
        "        self.q_device = tq.QuantumDevice(n_wires=self.n_wires)\n",
        "        self.ansatz = KernalAnsatz(\n",
        "        [   {'input_idx': [0], 'func': 'ry', 'wires': [0]},\n",
        "            {'input_idx': [1], 'func': 'ry', 'wires': [1]},\n",
        "            {'input_idx': [2], 'func': 'ry', 'wires': [2]},\n",
        "            {'input_idx': [3], 'func': 'ry', 'wires': [3]},])\n",
        "\n",
        "    def forward(self, x, y, use_qiskit=False):\n",
        "        # bsz=1\n",
        "        x = x.reshape(1, -1)\n",
        "        y = y.reshape(1, -1)\n",
        "        self.ansatz(self.q_device, x, y)\n",
        "        result = torch.abs(self.q_device.states.view(-1)[0])\n",
        "        return result"
      ],
      "metadata": {
        "id": "taGjJMVcLN2L"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "###Train the svm model from sklearn based on our quantum kernel.\n",
        "\n",
        "Define a kernel matrix function.\n",
        "\n",
        "Pass the kernel matrix function to SVC, call `.fit(X_train, y_train)` and the SVC object can start training.\n",
        "\n",
        "Predict and see the accuracy. The accuracy looks pretty well.\n"
      ],
      "metadata": {
        "id": "ckdg6zccLwF3"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "kernel_function = Kernel()\n",
        "def kernel_matrix(A, B):\n",
        "    return np.array([[kernel_function(a, b) for b in B] for a in A])\n",
        "\n",
        "svm = SVC(kernel=kernel_matrix).fit(X_train, y_train)\n",
        "predictions = svm.predict(X_test)\n",
        "print(accuracy_score(predictions, y_test))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "xS7zGXVDLwuY",
        "outputId": "78ef7a90-f2fe-4458-b911-2667209792cd"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1.0\n"
          ]
        }
      ]
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "collapsed_sections": [
        "pfwd2SNaOA4z"
      ],
      "name": "Quantum Kernel Method",
      "provenance": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
